package org.mte.sak.xml;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;

import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.mte.sak.reflect.ReflectHandler;


/**
 * <p>Associa una struttura XML ad un oggetto java, valorizzando l'oggetto
 *  con i valori presenti nella struttura.</p>
 * <p>L'ipotesi di base è che la struttura XML abbia come elementi
 * 	gli attributi della classe.</p>
 * <p>La struttura XML si ipotizza essere presente in un documento XML con altre
 * strutture equivalenti, ossia con diverse possibili istanze di una certa classe.</p>
 * <p>Es:</p>
 * <p>&lt;objects&gt;</p>
 * 		<p>&lt;object&gt;</p>
 * 		<p>&lt;attribute0&gt;&lt;attribute0&gt;</p>
 * 		<p>&lt;attribute1&gt;&lt;attribute1&gt;</p>
 * 		<p>&lt;attribute2&gt;&lt;attribute2&gt;</p>
 * 		<p>&lt;attribute3&gt;&lt;attribute3&gt;</p>
 * 		<p>&lt;/object&gt;</p>
 * <p>&lt;/objects&gt;</p>
 *
 * @author Marco Traversari
 * @version $Revision: 1.1 $ $Date: 2011-04-18 08:38:18 $
 *
 */
public class XMLClass extends XMLDocumentManager {

	/**
	 * Costruttore vuoto.
	 */
	public XMLClass() {
	}

	/**
	 * Carica il documento XML presente nel percorso specificato.
	 *
	 * @param filePath
	 * @throws JDOMException
	 */
	public XMLClass(String filePath) throws JDOMException, IOException {
		super(filePath);
	}

	/**
	 * <p>Carica nell'oggetto passato in input i valori trovati nel
	 * documento XML.</p>
	 * <p>Ipotizzando che nel documento XML ci siano una serie di valori
	 * relativi a oggetti differenti, per puntare all'oggetto desiderato
	 * È necessario specificare un elemento di riferimento del documento
	 * XML e un valore di tale elemento.</p>
	 * <p>Verrà caricato l'oggetto per il quale il valore letto nel documento XML
	 * per l'elemento <code>refElementName</code> è uguale al valore specificato
	 * <code>refElementValue</code>.</p>
	 *
	 * @param obj
	 * @param elementNameRef
	 * @param elementValueRef
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public void load(Object obj, String elementNameRef, String elementValueRef)
		throws Exception {
		Iterator iterator = getRootElement().getChildren().iterator();
		Field[] fields = obj.getClass().getDeclaredFields();
		boolean isFound = false;
		ReflectHandler rh = new ReflectHandler(obj);
		while (iterator.hasNext() && !isFound) {
			Element elementObj = (Element) iterator.next();
			String elementValue = elementObj.getChildText(elementNameRef);
			if (elementValueRef.equals(elementValue)) {
				for (int i = 0; i < fields.length; i++) {
					String attributeValue = elementObj.getChildText(fields[i].getName());
					rh.set(fields[i].getName(), attributeValue);
				}
				isFound = true;
			}
		}
	}

	/**
	 * <p>Carica tutti gli oggetti presenti nel documento XML.</p>
	 * <p>Ipotizzando che gli oggetti siano tutte istanze della classe
	 * specificata.</p>
	 *
	 * @param className
	 * @return objects
	 * @throws Exception
	 */
	@SuppressWarnings("rawtypes")
	public ArrayList<Object> loadAllObjects(String className) throws Exception {
		ArrayList<Object> objects = null;
		Iterator iterator = getRootElement().getChildren().iterator();
		ReflectHandler rh = new ReflectHandler(className);
		Field[] fields = rh.getObject().getClass().getDeclaredFields();
		while (iterator.hasNext()) {
			Element elementObj = (Element) iterator.next();
			for (int i = 0; i < fields.length; i++) {
				String attributeValue = elementObj.getChildText(fields[i].getName());
				rh.set(fields[i].getName(), attributeValue);
			}
			if (objects == null) {
				objects = new ArrayList<Object>();
			}
			objects.add(rh.getObject());
			rh = new ReflectHandler(className);
		}
		return objects;
	}
}